﻿using System;
using System.IO;

namespace ZeldaEncrypter
{
    /// <summary>
    /// Our main program class
    /// </summary>
    public static class Program
    {
        #region Methods this program can run

        /// <summary>
        /// Will be true if an argument is --encrypt or -e
        /// <para>NOTE: In the case of encryption, no other methods are run</para>
        /// </summary>
        private static bool Encrypt { get; set; }

        /// <summary>
        /// Will be true if an argument is --decrypt or -d
        /// <para>NOTE: In the case of decryption, no other methods are run</para>
        /// </summary>
        private static bool Decrypt { get; set; }

        /// <summary>
        /// Will be true if the user used an invalid syntax or if an argument is --help or -h
        /// <para>NOTE: In the case of printing help, no other methods are run</para>
        /// </summary>
        private static bool Help { get; set; }

        #endregion

        #region User input
        
        /// <summary>
        /// Will be true if the LAST argument before the input is --direct
        /// <para>NOTE: The last argument has to be valid data!</para>
        /// <para>NOTE: This feature is currently not implemented</para>
        /// </summary>
        private static bool DirectInput { get; set; }

        /// <summary>
        /// Will be set if the user used an invalid syntax
        /// </summary>
        private static bool InvalidSyntax { get; set; }

        /// <summary>
        /// Will be set through --key=[KEY]
        /// <para>The key to use (encryption keys can be also automatically generated)</para>
        /// </summary>
        private static string Key { get; set; }

        /// <summary>
        /// Will be set with the last argument
        /// <para>If "DirectInput" is set, this will be the direct input (Currently not used)</para>
        /// </summary>
        private static string Input { get; set; }

        #endregion

        #region Argument parsing method

        /// <summary>
        /// Parses all command line arguments and saves them in the suitable
        /// </summary>
        /// <param name="Argument"></param>
        private static void ParseArguments(string[] Argument)
        {
            // Check for valid array
            if (Argument == null)
                return;

            // Parse every argument and watch for syntax too
            for (int i = 0; i < Argument.Length; i++)
            {
                // If the input is already set, we do not allow more switches to be parsed ==> Invalid syntax
                // Since we currently do not support direct input, the last argument has to be an existing file
                if (!Input.Equals("") || (Argument.Length == (i + 1) && !File.Exists(Argument[i])))
                {
                    Help = true;
                    Encrypt = false;
                    Decrypt = false;
                    InvalidSyntax = true;
                    return;
                }
                // If the argument contains the key, we will use it
                if(Argument[i].ToLower().StartsWith("--key="))
                {
                    string[] SplittedKey = Argument[i].Split('=');
                    Key = SplittedKey[1];
                    continue;
                }
                // If we have the last argument and passed all above tests, we can use the argument as input
                if (Argument.Length == (i + 1))
                {
                    Input = Argument[i];
                    continue;
                }
                // Search for other switches
                switch (Argument[i].ToLower())
                {
                    case "--help":
                        Help = true;
                        Encrypt = false;
                        Decrypt = false;
                        return;
                    case "--encrypt":
                    case "-e":
                        Encrypt = true;
                        Decrypt = false;
                        Help = false;
                        break;
                    case "--decrypt":
                    case "-d":
                        Decrypt = true;
                        Encrypt = false;
                        Help = false;
                        break;
                    // If the switch is unknown ==> Invalid syntax
                    default:
                        Help = true;
                        Encrypt = false;
                        Decrypt = false;
                        InvalidSyntax = true;
                        return;
                }
            }
        }

        #endregion

        /// <summary>
        /// The starting point of our program
        /// </summary>
        /// <param name="args">All user inputs</param>
        static void Main(string[] args)
        {
            // Set the default values for all input variables
            Encrypt = false;
            Decrypt = false;
            Help = true;

            DirectInput = false;
            InvalidSyntax = false;
            Key = "";
            Input = "";

            // Parse all user input
            ParseArguments(args);

            // Since our program is currently always kind of invalid, we say, the user uses invalid syntax
            InvalidSyntax = true;

            // If the user used an invalid syntax, the program will stop immediately
            if (InvalidSyntax)
            {
                Console.WriteLine("You used an invalid syntax!");
                Console.WriteLine();
                // PrintHelp();
                return;
            }
            
            // TODO: Implement code for encryption and decryption
        }

        // TODO: Implement static PrintHelp() function
    }
}
